package com.cf.util;

import com.cf.constant.EnumReturnCode;
import com.cf.exception.BizException;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;


public class HttpUtil {


    private static RequestConfig requestConfig = null;

    private static PoolingHttpClientConnectionManager cm = null;


    static {
        requestConfig = RequestConfig.custom().setSocketTimeout(2000).setConnectTimeout(2000).setConnectionRequestTimeout(2000).build();
        LayeredConnectionSocketFactory sslsf = getCommonSSLSocketFactory();
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create().register("https", sslsf).register("http", new PlainConnectionSocketFactory()).build();
        cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        cm.setMaxTotal(200);
        cm.setDefaultMaxPerRoute(20);
    }

    private static LayeredConnectionSocketFactory getCommonSSLSocketFactory() {
        LayeredConnectionSocketFactory sslsf = null;
        try {
            sslsf = new SSLConnectionSocketFactory(SSLContext.getDefault());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return sslsf;
    }

    private static CloseableHttpClient getHttpClient() {
        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).build();
        return httpClient;
    }


    public static String get(String s) throws BizException {
        CloseableHttpClient httpClient = getHttpClient();

        HttpGet get = new HttpGet(s);
        get.setConfig(requestConfig);
        CloseableHttpResponse httpResponse = null;
        try {
            httpResponse = httpClient.execute(get);
            HttpEntity entity = httpResponse.getEntity();
            if (null != entity) {
                HttpEntity httpResponseEntity = httpResponse.getEntity();
                return EntityUtils.toString(httpResponseEntity, "utf-8");
            } else {
                return null;
            }
        } catch (Exception e) {
            throw new BizException(EnumReturnCode.ERROR.getCode(), "调用第三方失败！", e);
        } finally {
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }


    public static void getDownload(String s, String filePath) throws BizException {
        CloseableHttpClient httpClient = getHttpClient();
        HttpGet get = new HttpGet(s);
        get.setConfig(requestConfig);
        CloseableHttpResponse httpResponse = null;
        try {
            httpResponse = httpClient.execute(get);
            InputStream content = httpResponse.getEntity().getContent();
            File storeFile = new File(filePath);
            FileOutputStream fileOutputStream = new FileOutputStream(storeFile);
            int l;
            byte[] tmp = new byte[1024];
            while ((l = content.read(tmp)) != -1) {
                fileOutputStream.write(tmp, 0, l);// 注意这里如果用OutputStream.write(buff)的话，图片会失真，大家可以试试
            }
            fileOutputStream.flush();
            fileOutputStream.close();
        } catch (Exception e) {
            throw new BizException(EnumReturnCode.ERROR.getCode(), "调用第三方失败！", e);
        } finally {
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }


    public static String post(String s, Map<String, Object> parameter, boolean ignoreNull) throws BizException {
        CloseableHttpClient httpClient = getHttpClient();
        HttpPost post = new HttpPost(s);
        post.setConfig(requestConfig);
        CloseableHttpResponse httpResponse = null;
        try {

            List<NameValuePair> list = new ArrayList<NameValuePair>();
            if (parameter != null) {
                Iterator iterator = parameter.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, Object> elem = (Map.Entry<String, Object>) iterator.next();
                    if (elem.getValue() == null) {
                        if (ignoreNull) {
                            continue;
                        }
                    }
                    list.add(new BasicNameValuePair(elem.getKey(), elem.getValue().toString()));
                }
            }
            if (list.size() > 0) {
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "utf-8");
                post.setEntity(entity);
            }

            httpResponse = httpClient.execute(post);
            HttpEntity resEntity = httpResponse.getEntity();
            if (resEntity != null) {
                return EntityUtils.toString(resEntity, "utf-8");
            } else {
                return null;
            }
        } catch (Exception e) {
            throw new BizException(EnumReturnCode.ERROR.getCode(), "调用第三方失败！", e);
        } finally {
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    public static String post(String s, String data) throws BizException {
        CloseableHttpClient httpClient = getHttpClient();
        HttpPost post = new HttpPost(s);
        post.setConfig(requestConfig);
        CloseableHttpResponse httpResponse = null;
        try {
            post.setEntity(new StringEntity(data, "utf-8"));
            httpResponse = httpClient.execute(post);
            HttpEntity resEntity = httpResponse.getEntity();
            if (resEntity != null) {
                return EntityUtils.toString(resEntity, "utf-8");
            } else {
                return null;
            }
        } catch (Exception e) {
            throw new BizException(EnumReturnCode.ERROR.getCode(), "调用第三方失败！", e);
        } finally {
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    public static String postStrDownload(String s, String data, String filePath) throws BizException {

        CloseableHttpClient httpClient = getHttpClient();
        HttpPost post = new HttpPost(s);
        post.setConfig(requestConfig);
        CloseableHttpResponse httpResponse = null;
        try {
            post.setEntity(new StringEntity(data, "utf-8"));
            httpResponse = httpClient.execute(post);
            InputStream content = httpResponse.getEntity().getContent();
            File storeFile = new File(filePath);
            FileOutputStream fileOutputStream = new FileOutputStream(storeFile);
            int l;
            byte[] tmp = new byte[1024];
            while ((l = content.read(tmp)) != -1) {
                fileOutputStream.write(tmp, 0, l);// 注意这里如果用OutputStream.write(buff)的话，图片会失真，大家可以试试
            }
            fileOutputStream.flush();
            fileOutputStream.close();
        } catch (Exception e) {
            throw new BizException(EnumReturnCode.ERROR.getCode(), "调用第三方失败！", e);
        } finally {
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return null;
    }


    public static void postDownload(String s, Map<String, Object> parameter, String filePath) throws BizException {
        CloseableHttpClient httpClient = getHttpClient();
        HttpPost post = new HttpPost(s);
        post.setConfig(requestConfig);
        CloseableHttpResponse httpResponse = null;
        try {
            List<NameValuePair> list = new ArrayList<NameValuePair>();
            if (parameter != null) {
                Iterator iterator = parameter.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, Object> elem = (Map.Entry<String, Object>) iterator.next();
                    list.add(new BasicNameValuePair(elem.getKey(), elem.getValue().toString()));
                }
            }
            if (list.size() > 0) {
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "utf-8");
                post.setEntity(entity);
            }
            httpResponse = httpClient.execute(post);
            InputStream content = httpResponse.getEntity().getContent();
            if (content != null) {
                File storeFile = new File(filePath);
                FileOutputStream fileOutputStream = new FileOutputStream(storeFile);
                int l;
                byte[] tmp = new byte[1024];
                while ((l = content.read(tmp)) != -1) {
                    fileOutputStream.write(tmp, 0, l);// 注意这里如果用OutputStream.write(buff)的话，图片会失真，大家可以试试
                }
                fileOutputStream.flush();
                fileOutputStream.close();
            }
        } catch (Exception e) {
            throw new BizException(EnumReturnCode.ERROR.getCode(), "调用第三方失败！", e);
        } finally {
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
